﻿using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace XFFSM
{

    [CustomEditor(typeof(FSMTransitionInspectorHelper))]
    public class FSMTransitionInspector : Editor
    {

        private ReorderableList reorderableList;

        private Rect condition_left_rect;
        private Rect condition_right_rect;
        private Rect popRect;
         
        private GUIContent add_a_sets_of_conditions = null;

        private GUIContent auto_switch = null;

        private static Dictionary<ParameterType, FSMConditionInspector> conditionInspector = new Dictionary<ParameterType, FSMConditionInspector>();

        private Dictionary<int, ReorderableList> reorderables = new Dictionary<int, ReorderableList>();

        private bool autoSwitch;

        private void OnEnable() 
        {
            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) { return; }

            reorderableList = new ReorderableList(helper.transition.conditions, typeof(FSMConditionData), true, true, true, true);
            reorderableList.drawHeaderCallback += OnDrawHeaderCallback;
            reorderableList.onAddCallback += this.OnAddCallback;
            reorderableList.onRemoveCallback += this.OnRemoveCallback;
            reorderableList.drawElementCallback += this.DrawItem;

            autoSwitch = helper.transition.AutoSwtich;
        }

        public override void OnInspectorGUI()
        {
            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) { return; }

            EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);

            if (auto_switch == null)
                auto_switch = new GUIContent("AutoSwitch", "当条件为空时,是否自动切换?当前过渡的条件为空时可用!");



             
            EditorGUI.BeginDisabledGroup(!helper.transition.Empty);
            Rect rect = GUILayoutUtility.GetRect(0f, 20, GUILayout.ExpandWidth(expand: true));
            GUI.Label(rect, auto_switch);
            rect.Set(rect.width - 20, rect.y, 20, 20);
            if (helper.transition.Empty)
            {
                helper.transition.AutoSwtich = GUI.Toggle(rect, helper.transition.AutoSwtich, string.Empty);
            }
            else {
                GUI.Toggle(rect,false, string.Empty);
            }

            if (autoSwitch != helper.transition.AutoSwtich)
            {
                helper.controller.Save();
                autoSwitch = helper.transition.AutoSwtich;
            }
            GUILayout.Space(10);
            EditorGUI.EndDisabledGroup();

            reorderableList.list = helper.transition.conditions;
            reorderableList.DoLayoutList();

            GUILayout.Space(10);

            for (int i = 0; i < helper.transition.group_conditions.Count; i++)
            {
                GroupCondition condition = helper.transition.group_conditions[i];
                if (condition == null) continue;
                ReorderableList list = GetReorderableList(condition);
                if (list != null) 
                {                
                    list.list = condition.conditions;
                    list.DoLayoutList();
                    GUILayout.Space(10);
                }
            }

            


            if (add_a_sets_of_conditions == null)
                add_a_sets_of_conditions = new GUIContent("Add a set of conditions","添加一组条件");
             
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (helper.transition.group_conditions.Count > 0)
            {
                GUILayout.Label("注:当有多组条件时,其中一组满足,状态就会切换!", "CN StatusWarn");    
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            if (GUILayout.Button(add_a_sets_of_conditions, GUILayout.Width(260), GUILayout.Height(25))) 
            {
                helper.transition.group_conditions.Add(new GroupCondition());
                helper.controller.Save();
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
              
            EditorGUI.EndDisabledGroup();

        }

        protected override void OnHeaderGUI()
        {
            //base.OnHeaderGUI();
            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) { return; }

            GUILayout.BeginHorizontal();

            GUILayout.Label(EditorGUIUtility.IconContent("icons/processed/unityeditor/animations/animatorstatetransition icon.asset"),GUILayout.Width(30),GUILayout.Height(30));
            GUILayout.Label(string.Format("{0} -> {1}", helper.transition.fromStateName, helper.transition.toStateName));
            GUILayout.EndHorizontal();

            // 画一条 分隔的线 
            var rect = EditorGUILayout.BeginHorizontal();

            Handles.color = Color.black;
            Handles.DrawLine(new Vector2(rect.x, rect.y), new Vector3(rect.x + rect.width, rect.y));

            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

        }


        private static void InitConditionInspectors() {

            if (conditionInspector.Count == 0) {
                conditionInspector.Add(ParameterType.Bool, new FSMBoolConditionInspector());
                conditionInspector.Add(ParameterType.Float, new FSMFloatConditionInspector());
                conditionInspector.Add(ParameterType.Int, new FSMIntConditionInspector());
                conditionInspector.Add(ParameterType.Trigger, new FSMConditionInspector()); // 不需要做任何绘制 
            }

        }

        private void OnAddCallback(ReorderableList list) {

            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) { return; }
            //Debug.Log("添加条件");
            FSMConditionFactory.CreateCondition(helper.controller, helper.transition);
        }

        private void OnRemoveCallback(ReorderableList list)
        {

            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) return;

            FSMConditionFactory.DeleteCondition(helper.controller, helper.transition,list.index);
        }

        private void DrawItem(Rect rect, int index, bool isActive, bool isFocused) {

            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) { return; }

            var conditon = helper.transition.conditions[index];

            DrawItemExcute(rect, conditon);
        }

        private void DrawItemExcute(Rect rect, FSMConditionData condition) 
        {
            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) return;

            condition_left_rect.Set(rect.x, rect.y, rect.width / 2, rect.height);
            condition_right_rect.Set(rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height);

            if (helper.controller.parameters.Count > 0)
            {
                //tempContent.text = conditon.parameterName;
                if (EditorGUI.DropdownButton(condition_left_rect, new GUIContent(condition.parameterName), FocusType.Keyboard))
                {
                    // 弹出选择参数的弹框 TODO 
                    PopupWindow.Show(rect, new FSMSelectParamWindow(rect.width / 2, condition, helper.controller));
                
                   
                }
            }

            InitConditionInspectors();

            FSMParameterData parameter = helper.controller.GetParameterData(condition.parameterName);

            if (parameter == null)
            {
                EditorGUI.LabelField(condition_right_rect, "缺少参数!");
            }
            else
            {

                // 根据不同的参数类型绘制不同的内容
                if (conditionInspector.ContainsKey(parameter.parameterType))
                    // 进行绘制
                    if (conditionInspector[parameter.parameterType] != null)
                        conditionInspector[parameter.parameterType].OnGUI(condition_right_rect, condition, helper.controller);
                    else
                        Debug.LogErrorFormat("未查询到对应的绘制方式:{0}", parameter.parameterType);
            }

        }

        private void OnDrawHeaderCallback(Rect rect) 
        {
            GUI.Label(rect, "Conditions");
        }

        public ReorderableList GetReorderableList(GroupCondition condition) 
        {
            if (condition == null) 
                return null;

            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null)  
                return null; 

            int key = condition.GetHashCode();
            if (!reorderables.ContainsKey(key))
            {

                ReorderableList list = new ReorderableList(condition.conditions, typeof(FSMConditionData), true, true, true, true);
                list.drawHeaderCallback += (rect)=> {
                     
                    GUI.Label(rect, "Conditions");

                    rect.Set(rect.width - 10, rect.y + 1, 25, 25); 

                    if (GUI.Button(rect,EditorGUIUtility.IconContent("d__Menu"), "IconButton"))
                    {
                        ShowConditionMenu(condition);
                    }


                };
                list.onAddCallback += (a) => {
                    FSMConditionData data = FSMConditionFactory.CreateCondition(helper.controller);
                    condition.conditions.Add(data);
                    helper.controller.Save();
                };

                list.onRemoveCallback += (a) => 
                { 
                    if(a.index >= 0 && a.index < condition.conditions.Count)
                        condition.conditions.RemoveAt(a.index);
                    helper.controller.Save();
                };
                
                list.drawElementCallback += (rect,index,c,d) => 
                {
                    DrawItemExcute(rect, condition.conditions[index]);
                };
                reorderables.Add(key, list);
            }

            return reorderables[key];
        }


        private void ShowConditionMenu(GroupCondition condition)
        {
            FSMTransitionInspectorHelper helper = target as FSMTransitionInspectorHelper;
            if (helper == null) { return; }

            var genricMenu = new GenericMenu();

            genricMenu.AddItem(new GUIContent("Remove"), false, () =>
            {
                // 移除一组条件
                helper.transition.group_conditions.Remove(condition);
                helper.controller.Save();
            });
             
            genricMenu.ShowAsContext();
        }

    }

}

